#!/usr/bin/env python3
import argparse
import time

def parse_args():
    parser = argparse.ArgumentParser(description='中断统计工具')
    parser.add_argument('-c', '--cpu', type=int, default=-1,
                        help='指定要查看的CPU')
    parser.add_argument('-b', '--bindings', action='store_true',
                        help='输出指定CPU的中断绑定信息')
    parser.add_argument('-t', '--top', type=int, default=0,
                        help='查看一定时间内产生最多的中断')
    parser.add_argument('-i', '--interval', type=float, default=1.0,
                        help='指定时间间隔')
    return parser.parse_args()

def print_bindings(cpu):
    with open('/proc/interrupts') as f:
        for line in f:
            fields = line.split()
            if len(fields) > 0 and fields[0].endswith('-%d' % cpu):
                print(line.strip())

def print_top_interrupts(top, interval):
    interrupts1 = read_interrupts()
    time.sleep(interval)
    interrupts2 = read_interrupts()
    diffs = [(k, interrupts2[k] - interrupts1.get(k, 0)) for k in interrupts2]
    diffs.sort(key=lambda x: x[1], reverse=True)
    for i in range(min(top, len(diffs))):
        print('%-4s %10d' % (diffs[i][0], diffs[i][1]))

def read_interrupts():
    interrupts = {}
    with open('/proc/interrupts') as f:
        for line in f:
            fields = line.split()
            if len(fields) > 0 and fields[0].endswith(':'):
                interrupts[fields[0][:-1]] = sum([int(x) if x.isdigit() else 0 for x in fields[1:]])
    return interrupts

def main():
    args = parse_args()
    if args.cpu >= 0 and args.bindings:
        print_bindings(args.cpu)
    elif args.top > 0:
        while True:
            print_top_interrupts(args.top, args.interval)
    else:
        interrupts = read_interrupts()
        for irq in interrupts:
            print('%-4s %10d' % (irq, interrupts[irq]))

if __name__ == '__main__':
    main()